{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0",
   "metadata": {},
   "source": [
    "# Demo of the trait exception rewriting\n",
    "\n",
    "Traitlets results in very long stacktraces.  Look at the difference between these two stack traces.\n",
    "\n",
    "Watch this space,  These stacktraces still aren't great, but they are much better"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "from traitlets import Any, observe, HasTraits\n",
    "import six"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "class DumbBase(HasTraits):\n",
    "    first_trait = Any()\n",
    "    second_trait = Any()\n",
    "    third_trait = Any()\n",
    "\n",
    "    def __init__(self, val):\n",
    "        super().__init__()\n",
    "        self.first_trait = val\n",
    "        \n",
    "    def compute_first(self, val):\n",
    "        return val\n",
    "    \n",
    "    @observe('first_trait')\n",
    "    def handle_first(self, change):\n",
    "        self.second_trait = self.compute_first(self.first_trait)\n",
    "\n",
    "    def compute_second(self, val):\n",
    "        return val\n",
    "    \n",
    "    @observe('second_trait')\n",
    "    def handle_second(self, change):\n",
    "        self.third_trait = self.compute_second(self.second_trait)\n",
    "\n",
    "class ErrorSecond(DumbBase):\n",
    "    def compute_second(self, val):\n",
    "        1/0\n",
    "        \n",
    "ErrorSecond(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def exception_protect(func):\n",
    "    def wrapped(self, *args, **kwargs):\n",
    "        try:\n",
    "            func(self, *args, **kwargs)\n",
    "        except Exception as e:\n",
    "            if self.exception is None:\n",
    "                self.exception = sys.exc_info()\n",
    "            raise\n",
    "    return wrapped\n",
    "\n",
    "class SmartBase(HasTraits):\n",
    "    first_trait = Any()\n",
    "    second_trait = Any()\n",
    "    third_trait = Any()\n",
    "\n",
    "    def __init__(self, val):\n",
    "        super().__init__()\n",
    "        self.exception = None\n",
    "        try:\n",
    "            self.first_trait = val\n",
    "        except Exception as e:\n",
    "            # print(\"e\", sys.exc_info())\n",
    "            print(\"self.exception\", self.exception)\n",
    "            exc, exc1, tb = self.exception\n",
    "            six.reraise(exc, exc1, tb)\n",
    "        \n",
    "    def compute_first(self, val):\n",
    "        return val\n",
    "    \n",
    "    @observe('first_trait')\n",
    "    @exception_protect\n",
    "    def handle_first(self, change):\n",
    "        self.second_trait = self.compute_first(self.first_trait)\n",
    "\n",
    "    def compute_second(self, val):\n",
    "        return val\n",
    "    \n",
    "    @observe('second_trait')\n",
    "    @exception_protect\n",
    "    def handle_second(self, change):\n",
    "        try:\n",
    "            self.third_trait = self.compute_second(self.second_trait)\n",
    "        except Exception as e:\n",
    "            self.exception = sys.exc_info()\n",
    "            raise\n",
    "\n",
    "class ErrorSecondSmart(SmartBase):\n",
    "    def compute_second(self, val):\n",
    "        1/0\n",
    "ab = ErrorSecondSmart(5)\n",
    "ab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
